Skip to content

fix: keep conda and virtualenv activation across session restore - #2367

Open
happysnehal111-del wants to merge 1 commit into
herdrdev:masterfrom
happysnehal111-del:fix/restore-pane-virtual-env
Open

fix: keep conda and virtualenv activation across session restore#2367
happysnehal111-del wants to merge 1 commit into
herdrdev:masterfrom
happysnehal111-del:fix/restore-pane-virtual-env

Conversation

@happysnehal111-del

Copy link
Copy Markdown

Problem

A pane that was working inside an activated conda environment or virtualenv comes back from a session restore on the shell's default environment. The agent resumes, but against the wrong interpreter — python, pip, and anything else installed into the environment resolve outside it.

Restore spawns the pane's shell with an empty PaneLaunchEnv, and the snapshot has nowhere to record an activation, so there is nothing to hand back.

How the environment is read

A shell mutates its own environment in place when it activates one, and that mutation is not visible from outside the process. What is visible is the environment a process was launched with, so the pane's foreground process group leader — the command the shell started — carries the activation that was in effect when it began. In the case that matters, that process is the agent.

The primitives for this were already here: /proc/<pid>/environ on Linux, KERN_PROCARGS2 on macOS, and the PEB read on Windows. This adds one function per platform on top of them, and a fallback stub elsewhere.

What gets stored

Only the activation prefix and its display name, not a copy of PATH. PATH is rebuilt from the prefix on restore, so a restored pane follows the current machine rather than being pinned to whatever it looked like when the snapshot was written. Entries already on the inherited PATH are not repeated, so repeated restores cannot grow it.

PaneSnapshot.virtual_env is optional and skipped when absent, so SNAPSHOT_VERSION stays at 3 and sessions written by this build still load on older ones.

conda's automatic base activation

Restored panes come back as interactive login shells, so they re-run the user's rc files, and conda's init hook activates base by default. That runs after the environment is handed in and replaces it. It shadows a restored virtualenv too, because base lands ahead of it on PATH. CONDA_AUTO_ACTIVATE and CONDA_AUTO_ACTIVATE_BASE are therefore set to false for restored panes that have a recorded environment — both spellings, since conda renamed the setting in 25.x. Panes without a recorded environment are untouched and still auto-activate base as before.

Testing

  • cargo fmt --check, cargo clippy --all-targets -- -D warnings, and the cross-target Windows clippy from just windows-lint are clean.
  • cargo nextest run passes except for three tests that fail identically on an unmodified master on this machine: live_handoff_keeps_agent_started_pane_after_agent_exits, live_handoff_keeps_unmanaged_agent_name_bound_to_saved_session, and pane_info_and_subscriptions_expose_done_agent_status.
  • Verified end to end on macOS against a real build in an isolated config directory: activate an environment in a pane, start a long-running process, stop the server, relaunch. Both conda and venv come back with the right prefix and with python resolving into the environment.
  • The Linux and Windows paths are compile-checked but not exercised on hardware — I don't have either available.

@kangal-bot kangal-bot added the ai-review Trigger automated AI reviews for pull requests admitted by the PR gate label Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change detects Conda and venv activations across platforms. Pane snapshots store activation metadata. Workspace capture, terminal restoration, and deferred agent resume preserve this state and apply its environment variables to launches.

Changes

Virtual environment persistence

Layer / File(s) Summary
Activation model and environment parsing
src/platform/mod.rs
Adds Conda and venv activation types, process-environment parsing, PATH construction, launch overrides, and tests.
Foreground process detection
src/platform/*.rs, src/pane.rs, src/terminal/runtime.rs, src/workspace/tab.rs
Reads process environments on supported platforms and exposes the foreground activation through pane, terminal, and tab runtimes.
Snapshot capture and compatibility
src/persist/snapshot.rs, src/terminal/state.rs
Snapshots optionally serialize virtual-environment metadata, restore supported kinds, preserve absent values, and ignore unknown kinds.
Restored launch integration
src/persist/restore.rs, src/pane.rs, src/app/agent_resume.rs, docs/next/CHANGELOG.md
Restored terminals and deferred agent resumes apply activation environment overrides and retain reconstructed activation state. Cold-restore tests verify Conda metadata and removal of missing environments.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟡 Moderate · up to a27b8

The PR changes session restoration to preserve Conda and virtualenv environments, but the current head can still restore an idle pane or live-handoff shell with the wrong interpreter, and the supplied evidence retains a Windows test assertion failure. Persisted environment prefixes also affect executable lookup without ownership validation. The PR needs fixes or explicit owner acceptance before merge.

Sequence Diagram(s)

sequenceDiagram
  participant Tab
  participant TerminalRuntime
  participant PaneRuntime
  participant PlatformProcessReader
  participant Snapshot
  participant Restore
  participant Terminal
  Tab->>TerminalRuntime: request foreground_virtual_env
  TerminalRuntime->>PaneRuntime: request foreground_virtual_env
  PaneRuntime->>PlatformProcessReader: read process environment
  PlatformProcessReader-->>PaneRuntime: return VirtualEnvActivation
  PaneRuntime-->>TerminalRuntime: return activation
  TerminalRuntime-->>Tab: return activation
  Tab->>Snapshot: capture activation
  Snapshot-->>Restore: provide saved activation
  Restore->>Terminal: apply activation during launch
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.87% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 92 functions across 12 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the session-restore problem, the platform-specific implementation, stored activation data, compatibility behavior, and testing results.
Title check ✅ Passed The title clearly and concisely summarizes the primary change: preserving Conda and virtualenv activation across session restore.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 19bca225-41b0-4f49-8c9d-8d125c9b9874

📥 Commits

Reviewing files that changed from the base of the PR and between eb93ec8 and 7d17ab3.

📒 Files selected for processing (12)
  • src/app/agent_resume.rs
  • src/pane.rs
  • src/persist/restore.rs
  • src/persist/snapshot.rs
  • src/platform/fallback.rs
  • src/platform/linux.rs
  • src/platform/macos.rs
  • src/platform/mod.rs
  • src/platform/windows.rs
  • src/terminal/runtime.rs
  • src/terminal/state.rs
  • src/workspace/tab.rs

Comment thread src/pane.rs
Comment thread src/persist/restore.rs Outdated
Comment thread src/persist/snapshot.rs
Comment thread src/platform/mod.rs
Comment thread src/platform/mod.rs
@happysnehal111-del
happysnehal111-del force-pushed the fix/restore-pane-virtual-env branch from 7d17ab3 to e6308ed Compare August 5, 2026 16:50
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown

Greptile Summary

The PR persists conda and virtualenv activation metadata with pane snapshots and reapplies it when restoring panes or resuming agents.

  • Detects activation from foreground-process environments across Linux, macOS, and Windows.
  • Stores only the environment kind, prefix, and display name.
  • Reconstructs activation variables and PATH during pane launch.
  • Preserves compatibility with snapshots where the optional field is absent.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope.

No blocking failure remains.

Important Files Changed

Filename Overview
src/platform/mod.rs Defines activation metadata, parsing, and cross-platform launch-environment reconstruction.
src/persist/snapshot.rs Adds optional virtual-environment snapshot capture while retaining additive-format compatibility.
src/persist/restore.rs Validates saved prefixes and carries restored activation into terminal launch and deferred resume state.
src/pane.rs Applies activation variables during pane launch and exposes foreground activation detection.
src/app/agent_resume.rs Reuses the terminal’s restored activation when spawning a resumed agent.
src/platform/linux.rs Reads activation from procfs with process-state and WSL safeguards.
src/platform/macos.rs Reads activation from the macOS process argument and environment block.
src/platform/windows.rs Reads and parses activation variables from the target process environment.

Sequence Diagram

sequenceDiagram
  participant P as Foreground process
  participant S as Snapshot capture
  participant D as Session snapshot
  participant R as Session restore
  participant T as Restored terminal
  P->>S: Read activation environment
  S->>D: Store kind, prefix, and name
  D->>R: Load optional virtual_env
  R->>R: Validate prefix and rebuild PATH
  R->>T: Launch with activation variables
Loading

Reviews (3): Last reviewed commit: "fix: keep conda and virtualenv activatio..." | Re-trigger Greptile

@ogulcancelik ogulcancelik left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs another pass before merge:

  1. process_virtual_env() unconditionally reads /proc/<pid>/environ during snapshot capture. that reintroduces the exact remote-memory-backed WSL stall guarded by #2179. please rebase after #2179 and apply the same state/WSL safety policy to this read.
  2. launch_env(std::env::var("PATH")) rebuilds from the server process PATH. for deferred resume this can overwrite the effective pane-launch PATH, including the local-attach refresh in #2854. derive from the effective launch environment after that work is reconciled instead.
  3. add Windows unit coverage for virtual_env_from_utf16 and Windows conda/venv path construction; this path is currently only compile-checked.
  4. because snapshot capture now adds a synchronous process-environment read per pane on the main loop, report 1-pane versus 15-pane save-capture scaling before merge.

please also add the user-facing changelog entry and rerun checks and both review bots on the rebased head.

@happysnehal111-del
happysnehal111-del force-pushed the fix/restore-pane-virtual-env branch from e6308ed to 69dd516 Compare August 28, 2026 13:48
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 53bbeae9-2933-4b77-97b9-7f6cfdc80170

📥 Commits

Reviewing files that changed from the base of the PR and between 7b675f4 and 69dd516.

📒 Files selected for processing (13)
  • docs/next/CHANGELOG.md
  • src/app/agent_resume.rs
  • src/pane.rs
  • src/persist/restore.rs
  • src/persist/snapshot.rs
  • src/platform/fallback.rs
  • src/platform/linux.rs
  • src/platform/macos.rs
  • src/platform/mod.rs
  • src/platform/windows.rs
  • src/terminal/runtime.rs
  • src/terminal/state.rs
  • src/workspace/tab.rs
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/terminal/runtime.rs
  • src/persist/restore.rs
  • src/workspace/tab.rs
  • src/platform/windows.rs
  • src/platform/macos.rs
  • src/platform/mod.rs
  • src/platform/fallback.rs
  • src/terminal/state.rs
  • src/app/agent_resume.rs
  • src/persist/snapshot.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Comment thread src/pane.rs
Comment on lines +3145 to +3173
#[test]
fn pane_launch_env_builds_the_activation_path_on_the_effective_launch_path() {
// Anything that sets PATH ahead of the activation has to survive it,
// so the activation is composed against the value the pane would have
// launched with rather than against the server's own PATH.
let mut cmd = CommandBuilder::new("shell");
let launch_env =
PaneLaunchEnv::from_extra(vec![("PATH".to_string(), "/refreshed/bin".to_string())])
.with_virtual_env(Some(crate::platform::VirtualEnvActivation {
kind: crate::platform::VirtualEnvKind::Conda,
prefix: "/opt/conda/envs/web".into(),
name: Some("web".to_string()),
}));

apply_pane_launch_env(&mut cmd, &launch_env);

let path = cmd.get_env("PATH").expect("expected PATH");
assert_eq!(
std::env::split_paths(path).collect::<Vec<_>>(),
[
std::path::PathBuf::from("/opt/conda/envs/web/bin"),
std::path::PathBuf::from("/refreshed/bin"),
]
);
assert_eq!(
cmd.get_env("CONDA_PREFIX"),
Some(std::ffi::OsStr::new("/opt/conda/envs/web"))
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Gate this Unix-specific test.

On Windows, Conda activation adds the prefix and five Windows-specific directories. This assertion expects only <prefix>/bin and /refreshed/bin. Windows test runs will fail.

Add #[cfg(not(windows))] to this test, or add a Windows-specific expected path list.

As per coding guidelines: “Rust platform-specific code must be compile-gated.”

Source: Coding guidelines

A pane working inside an activated conda environment or virtualenv came
back from restore on the shell's default environment, so an agent resumed
into that pane ran against the wrong interpreter.

Panes now record the activation prefix alongside their cwd, and restore
hands it back to the shell it spawns, including the deferred spawn that
resumes an agent. PATH is rebuilt from the prefix instead of replayed
from the snapshot so a restored pane follows the current machine, and an
environment that has been removed since the save is dropped rather than
re-entered. The restored shell re-runs the user's rc files, so conda's
automatic base activation is suppressed for it; otherwise base lands on
PATH ahead of whatever was restored.

The activation is carried on PaneLaunchEnv rather than expanded into
launch variables at the call site, so its PATH is built from the PATH the
pane actually launches with instead of the server's own.

Reading a foreground process environment on Linux now goes through the
same state and WSL guards as the other remote-memory-backed proc reads.
@happysnehal111-del
happysnehal111-del force-pushed the fix/restore-pane-virtual-env branch from 69dd516 to a27b82d Compare August 28, 2026 14:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd7ef60e-fd86-431a-9d2a-b3ca6ba3cb4e

📥 Commits

Reviewing files that changed from the base of the PR and between 69dd516 and a27b82d.

📒 Files selected for processing (1)
  • src/pane.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Comment thread src/pane.rs
Comment on lines +3056 to +3060
let foreground = crate::platform::foreground_process_group_id(pid)?;
// An idle prompt leaves the shell itself in the foreground, and the
// shell's own activation is the part that cannot be read.
if foreground == pid {
return None;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Preserve activation at an idle shell prompt.

Line 3059 returns None when the shell is foreground. After a user activates Conda or a venv and returns to the prompt, normal session capture takes this branch. src/workspace/tab.rs:598 then receives no activation, so the restored pane loses the environment.

Record an activation state that remains available at the prompt, such as through shell integration, instead of treating an idle shell as having no activation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Trigger automated AI reviews for pull requests admitted by the PR gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants